<template>
	<div>
		<el-dialog v-model="dialogVisible" :title="roleId ? '编辑角色' : '新增角色'" top="5vh">
			<el-form :model="roleForm" labelWidth="70">
				<el-form-item label="角色名称">
					<el-input v-model="roleForm.roleName" placeholder="请输入角色名称"></el-input>
				</el-form-item>
				<el-form-item label="权限字符">
					<el-input placeholder="请输入权限字符" v-model="roleForm.rolePerm"></el-input>
				</el-form-item>
				<el-form-item label="状态">
					<el-radio-group v-model="roleForm.enabled">
						<el-radio v-for="item in dicts.system_global_status" :label="Number(item.v)">{{ item.k }}</el-radio>
					</el-radio-group>
				</el-form-item>
				<el-form-item label="菜单权限">
					<el-checkbox v-model="permission.isFold" @change="toggleFold">展开/折叠</el-checkbox>
					<el-checkbox v-model="permission.isSelectAll" @change="toggleSelectAll">全选/全不选</el-checkbox>
					<el-checkbox v-model="permission.isLink">父子（联动/不联动）</el-checkbox>
					<el-tree class="tree" style="height: 170px;width: 100%; overflow: auto;" ref="elTreeRef"
						:data="permission.treeList" :props="permission.treeProps" :check-strictly="!permission.isLink"
						show-checkbox node-key="id" />
				</el-form-item>
				<el-form-item label="备注">
					<el-input type="textarea" maxlength="200" show-word-limit placeholder="请输入内容"
						v-model="roleForm.descript"></el-input>
				</el-form-item>
			</el-form>
			<template #footer>
				<el-button @click="dialogVisible = false">取消</el-button>
				<el-button type="primary" @click="onSubmit">确认</el-button>
			</template>
		</el-dialog>
	</div>
</template>

<script setup lang="ts">
import { getMenuPageApi, getRoleGetApi, postRoleAddApi, postRoleUpdateApi } from '@renderer/api/role';
import { useDicts } from '@renderer/composables/dicts';
import { IRoleMenuItem } from '@renderer/interface/role';
import { CheckboxValueType, ElTree } from 'element-plus';
import { onMounted, ref, watch } from 'vue';
import normalizeMenuList from './normalizeMenuList'

// 父组件传参
const props = defineProps<{
	roleId: string
}>()
// 自定义事件
const emits = defineEmits(['addRoleSuccess'])
// 接收父组件的 v-model
const dialogVisible = defineModel({ default: false })

/* 表单数据 */
const roleFormValue = () => ({
	roleName: '',
	rolePerm: '',
	enabled: undefined,
	descript: ''
})
const roleForm = ref<any>(roleFormValue())
const { dicts } = useDicts(['system_global_status'])
// 菜单树实例对象
const elTreeRef = ref<InstanceType<typeof ElTree>>()
const permission = ref<{
	treeList: IRoleMenuItem[]
	treeProps: {
		label: string
	}
	isFold: boolean
	isSelectAll: boolean
	isLink: boolean
}>({
	treeList: [],
	treeProps: {
		label: 'name'
	},
	isFold: false,
	isSelectAll: false,
	isLink: true,
})
// 获取菜单树数据
const getMenuTreeData = async () => {
	const { code, data: { records } } = await getMenuPageApi({
		current: '1',
		size: '999',
		enabled: '1'
	})
	if (code === '200') {
		permission.value.treeList = normalizeMenuList(records)
	}
}
// 根据角色id获取角色详情数据
const getRoleGetData = async () => {
	const { code, data: { role, permissions } } = await getRoleGetApi(props.roleId)
	if (code !== '200') return

	roleForm.value = role
	// 根据权限设置
	elTreeRef.value?.setCheckedKeys(permissions)
}

/* 菜单树 */
// 展开/折叠
const toggleFold = (val: CheckboxValueType) => {
	const nodesMap = elTreeRef.value!.store.nodesMap
	Object.keys(nodesMap).forEach(key => {
		nodesMap[key].expanded = val as boolean
	})
}
// 全选/全不选
const toggleSelectAll = (val: CheckboxValueType) => {
	const nodesMap = elTreeRef.value!.store.nodesMap
	Object.keys(nodesMap).forEach(key => {
		nodesMap[key].setChecked(val as boolean)
	})
}

/* 确认按钮 */
// 提交角色数据
const postRoleData = async () => {
	const postRoleApi = roleForm.value.id ? postRoleUpdateApi : postRoleAddApi
	const { code } = await postRoleApi({
		...roleForm.value,
		permissionIds: elTreeRef.value?.getCheckedKeys() as string[]
	})
	if (code !== '200') return

	ElMessage({
		type: 'success',
		message: roleForm.value.id ? '修改角色成功~' : '添加角色成功~'
	})
	dialogVisible.value = false

	// 通知父组件
	emits('addRoleSuccess')
}
// 点击确认按钮
const onSubmit = () => {
	postRoleData()
}

onMounted(() => {
	getMenuTreeData()
})
watch(dialogVisible, () => {
	if (dialogVisible.value) {
		// 打开 dialog 时获取数据
		if (props.roleId) {
			getRoleGetData()
		}
	} else {
		// 关闭 dialog 时清空数据
		roleForm.value = roleFormValue()
		toggleSelectAll(false)
	}
})
</script>

<style scoped lang="scss">
.tree {
	margin-top: .5rem;
	background-color: #fff;
	border: 1px solid #dcdfe6;
	border-radius: 4px;
}
</style>